package de.hsma.srn.model.key;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashSet;
import java.util.Observable;

import com.thoughtworks.xstream.XStream;

public class KeyBoxModel extends Observable {
	/*
	 * Members
	 */
	/**
	 * The name of the user this key box is assigned to - needed only for internal xml serialisation (filename!)
	 */
	private String mUserName;
	/**
	 * List of keys assigned to me
	 */
	private HashSet<KeyPackageModel> mAssignedKeys;
	/**
	 * List of my own keys (created by me with my own files)
	 */
	private HashSet<MasterKeyPackageModel> mOwnKeys;

	
	/*
	 * Getter & Setter
	 */
	/**
	 * 
	 * @return assignedKeys
	 */
	public HashSet<KeyPackageModel> getAssignedKeys() {
		return mAssignedKeys;
	}
	/**
	 * 
	 * @return ownKeys
	 */
	public HashSet<MasterKeyPackageModel> getOwnKeys() {
		return mOwnKeys;
	}
	
	
	/*
	 * Constructor
	 */
	/**
	 * Creates a new Key Box
	 */
	public KeyBoxModel(String userName) {
		this.mUserName = userName;
		this.mAssignedKeys = new HashSet<KeyPackageModel>();
		this.mOwnKeys = new HashSet<MasterKeyPackageModel>();
	}
	

	/*
	 * Methods
	 */
	/**
	 * Add an key (or master key) to this KeyBox.
	 * Existing keys will be overwritten!
	 * @param key to add
	 */
	public void add(KeyPackageModel key) {
		this.remove(key);
		System.out.println("[MODEL] Giving " + this.mUserName + " a key!");
		if(key instanceof MasterKeyPackageModel) {
			this.mOwnKeys.add((MasterKeyPackageModel) key);
		} else {
			this.mAssignedKeys.add(key);
		}
		// Save changes
		this.save();
	}
	/**
	 * Removes the given key
	 * @param key to remove
	 * @return true if key could be removed
	 */
	public boolean remove(KeyPackageModel key) {
		if(key==null) { return false; }
		if(key instanceof MasterKeyPackageModel) {
			for(KeyPackageModel select : this.mOwnKeys) {
				if(select.getFilePath().equalsIgnoreCase(key.getFilePath())) {
					this.mOwnKeys.remove(select);
					// Save changes
					this.save();
					return true;
				}
			}
		} else {
			for(KeyPackageModel select : this.mAssignedKeys) {
				if(select.getFilePath().equalsIgnoreCase(key.getFilePath())) {
					this.mAssignedKeys.remove(select);
					// Save changes
					this.save();
					return true;
				}
			}
		}
		return false;
	}
	/**
	 * Returns the key package with the given filePath.
	 * The type of the returned key package could also be an master key package or
	 * even null if nothing was found!
	 * @param filePath to look for
	 * @return key package or null if nothing was found
	 */
	public KeyPackageModel get(String filePath) {
		for(KeyPackageModel keyPackage : this.mAssignedKeys) {
			if(keyPackage.getFilePath().equalsIgnoreCase(filePath)) {
				return keyPackage;
			}
		}
		for(MasterKeyPackageModel keyPackage : this.mOwnKeys) {
			if(keyPackage.getFilePath().equalsIgnoreCase(filePath)) {
				return keyPackage;
			}
		}
		return null;
	}
	/**
	 * Saves this keybox
	 */
	protected void save() {
		XStream stream = new XStream();
		OutputStream out;
		File homeDirectory = new File("Users/" + this.mUserName);
		if(!homeDirectory.exists()) {
			homeDirectory.mkdir();
		}
		try {
			
			out = new FileOutputStream(homeDirectory.getPath() + "/keybox");
			stream.toXML(this, out);
			out.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}